-
Notifications
You must be signed in to change notification settings - Fork 58
Add a macro to make initialization easier #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
6bca433
to
6335bb8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me, thanks! Just a bit of nitpicks and it should be mergable.
9951db6
to
080581e
Compare
@zeenix I have made improvements based on the suggestions, and I added a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
@JalonWong I'll merge soon but I want to first give others a chance to have a look. CC @adamgreig @sgued |
My only thought is that people are likely to want to configure where the backing store for the heap is located in memory using
|
How about a combination of these two: we add the optional argument for the linker section and if people need to add other attributes, they just don't use the macro? |
6d4171b
to
1e17f59
Compare
@zeenix @adamgreig If someone want to use |
f447854
to
d47bd8a
Compare
src/llff.rs
Outdated
/// - This function must be called exactly ONCE. | ||
/// - `size > 0` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the assertions in place now, these are no longer a safety issue but rather just panic scenarios, so I'd change the heading here from Safety
to Panics
and update the wording of the section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how to express it. Could you provide some content?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give it a try first? I can help if/when needed. Just try to keep the changes to minimum and focus on adapting the wording.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still not done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cllipy requires a Safety
section, so I added the content under it.
Maybe we have to make this function safe to change it to Panics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cllipy requires a
Safety
section, so I added the content under it. Maybe we have to make this function safe to change it toPanics
If there is no safety issues anymore, yeah I think we should do that.
Still, please bring back the changes I requested. If there are no safety issues anymore but for some reason we still want this to be declared unsafe
, we should just say so in the Safety
section (separate from Panics
): Currently this function is completely safe.
@sgued What do you think of removing unsafe
from the function? I think it's not considered a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The init
function takes pointers as arguments so it still needs to be unsafe
because safe code could generate bogus pointers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right. I had assumed that @JalonWong did his homework but I guess not. :) So @JalonWong we need both Safety and Panics sections then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zeenix Yes, I noticed that the arguments need unsafe
. I wonder if we should continue to modify it? Or what content should be written in the Safety section if we keep both Safety and Panics sections?
@@ -8,6 +8,7 @@ use linked_list_allocator::Heap as LLHeap; | |||
/// A linked list first fit heap. | |||
pub struct Heap { | |||
heap: Mutex<RefCell<LLHeap>>, | |||
once_flag: Mutex<Cell<bool>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So my question was that why do we need a separate boolean field with it's own mutex when could use core::cell::OnceCell
? We can bump the MSRV if that's an issue here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I use Mutex
because it's a hint that we should use it in a critical section. Since the Mutex
of critical_section
is basically an UnsafeCell
, I think it's not bad.
And because Sync
is not implemented for OnceCell
, using it directly might not be safe enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not talking about use of Mutex. I'm questing the need for the addition of an extra field. Why can't heap
be changed to Mutex<OnceCell<LLHpeap>>
? If it can be, then we don't need another field here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds good, and I have tried it. It turns out that OnceCell
needs a mutable reference to call get_mut()
, but the Mutex
of critical_section
can not provide it. It seems that the RefCell
is necessary here.
Unless I do Mutex<RefCell<OnceCell<LLHeap>>>
or Mutex<OnceCell<RefCell<LLHeap>>>
. Are they better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds good, and I have tried it. It turns out that
OnceCell
needs a mutable reference to callget_mut()
, but theMutex
ofcritical_section
can not provide it. It seems that theRefCell
is necessary here.
Right, I keep forgetting this. It's just weird for something to be called a "Mutex" can it not providing interior mutability. I think it's a big naming failure but naming things is hard. :)
Unless I do
Mutex<RefCell<OnceCell<LLHeap>>>
orMutex<OnceCell<RefCell<LLHeap>>>
. Are they better?
Not ideal but IMO better than having a separate field.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like adding one more branch to each allocation.
You mean indirection (cause I don't see any branches because combinators are being used)? I don't love it either but I think the code is more robust if the fate of a field is not decided by another (especially if the fate involves safety). This is one of the reasons I fell in love with Rust: in C and C++ (and other languages) locks guarding a state are separate and therefore vulnerable to programmers making a mistake. In Rust, we have the guarded state enclosed in the locks. I think this is a very similar case here.
As said in #103 (comment) this does not fully solve the safety issue.
I'm confused, that comment just says that the function still need to be marked as unsafe
. That's not too relevant to the overall picture IMO. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean indirection (cause I don't see any branches because combinators are being used)? I don't love it either but I think the code is more robust if the fate of a field is not decided by another (especially if the fate involves safety).
The allocation functions now have an additional unwrap
. As seen in rust-embedded/heapless#598 that can seriously impact performance.
This is also a breaking change because now allocating with an empty heap panics, while before it just behaved as out of memory.
I'm confused, that comment just says that the function still need to be marked as unsafe. That's not too relevant to the overall picture IMO. 🤔
My point is that sacrificing performance for a bit of safety but not full safety is not that clear-cut for me. Especially for something like this that is pretty easy to use safely in the embedded use case, where performance can be important.
If the cost of the check was only in the init
function it would be fine, but here it's not, it affects every allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean indirection (cause I don't see any branches because combinators are being used)? I don't love it either but I think the code is more robust if the fate of a field is not decided by another (especially if the fate involves safety).
The allocation functions now have an additional
unwrap
. As seen in rust-embedded/heapless#598 that can seriously impact performance.
Right, I didn't think of performance penalty. Now that you have mentioned it, it is indeed a good argument. Sorry @JalonWong for making you go down that road. Let's go with your previous approach but first let's make sure both I and @sgued agree on that as well.
(BTW I think you meant to link to rust-embedded/heapless#598).
This is also a breaking change because now allocating with an empty heap panics, while before it just behaved as out of memory.
The docs say "Obey these or Bad Stuff will happen" about "n == 0" so we promised them more pain that panic brings so IMO this makes it the opposite of a breaking change. :)
My point is that sacrificing performance for a bit of safety but not full safety is not that clear-cut for me.
I don't think you presented this argument before but now that you have, I agree. :)
Do you agree with @JalonWong's previous approach (with two fields)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docs say "Obey these or Bad Stuff will happen" about "n == 0" so we promised them more pain that panic brings so IMO this makes it the opposite of a breaking change. :)
I meant allocating without ever calling init
.
This can be done with safe code. But yes we can argue it's not really an issue.
Do you agree with @JalonWong's previous approach (with two fields)?
I can be ok with that. Just a bool
in the same RefCell as the heap RefCell
that is checked on init
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2ec6dbe
to
bb571a2
Compare
No description provided.